package com.scs.application.modules.finance.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.scs.application.core.query.QueryContext;
import com.scs.application.core.service.BaseServiceImpl;
import com.scs.application.core.utils.BeanUtils;
import com.scs.application.core.utils.DateUtils;
import com.scs.application.modules.finance.dto.*;
import com.scs.application.modules.finance.entity.BillItem;
import com.scs.application.modules.finance.entity.ThirdParty;
import com.scs.application.modules.finance.enums.BillStatus;
import com.scs.application.modules.finance.mapper.BillItemMapper;
import com.scs.application.modules.finance.service.BillItemService;
import com.scs.application.modules.finance.service.ThirdPartyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 */
@Service
public class BillItemServiceImpl extends BaseServiceImpl<BillItemMapper, BillItem> implements BillItemService {


    @Autowired
    private ThirdPartyService thirdPartyService;


    /**
     * 保存记帐单和结算单关系
     *
     * @param billSettlementDTO
     * @return
     */
    @Override
    public void saveSettlement(BillSettlementDTO billSettlementDTO) {
        List<BillItem> billItemList = billSettlementDTO.getBillItemIds().stream().map(id -> {
            BillItem billItem = new BillItem();
            billItem.setId(id);
            billItem.setSettlementId(billSettlementDTO.getOperateFlag() > 0 ? billSettlementDTO.getSettlementId() : "0")
                    .setStatus(BillStatus.SETTLEMENT.getStatus());
            return billItem;
        }).collect(Collectors.toList());

        if (billItemList.size() > 0) {
            super.updateBatchById(billItemList);
        }
        baseMapper.calculateSettlementPrice(billSettlementDTO.getSettlementId());
    }

    @Override
    public void updateBillItemByHrp() {
        List<ThirdParty> thirdPartylist = thirdPartyService.list(Wrappers.<ThirdParty>query().eq("IFNULL(patient_no,0)", 0)
                .gt("oprt_date", DateUtils.format(DateUtils.addDays(new Date(), -90), "yyyy-MM-dd"))
                .orderByAsc("oprt_date"));
        updateBillItemByHrpHigh();
        updateBillItemByHrpLow(thirdPartylist);
        //updateBillItemByHrpSpecial(thirdPartylist);

    }

    /**
     * 存在sn 和数量不相等 特殊处理
     *
     * @param thirdPartylist
     */
    private void updateBillItemByHrpSpecial(List<ThirdParty> thirdPartylist) {
        List<BillItem> itemList = new ArrayList<>();
        List<BillItemHrp> billItemHrpList = baseMapper.billItemList("0");
        Map<HrpOrderKey, List<BillItemHrp>> BillItemHrpMap = billItemHrpList.stream().collect(
                Collectors.groupingBy(o -> {
                            if (o.getSkuQty() > 0) {
                                return new HrpOrderKey("", o.getSn(), o.getHrpCode(), o.getDeptCode(), 1D, "");
                            } else {
                                return new HrpOrderKey("", o.getSn(), o.getHrpCode(), o.getDeptCode(), -1D, "");
                            }

                        }
                ));


        Map<HrpOrderKey, List<ThirdParty>> ThirdPartyMap = thirdPartylist.stream().collect(
                Collectors.groupingBy(o -> {
                            if (o.getSkuQty() > 0) {
                                return new HrpOrderKey("", o.getSn(), o.getInvCode(), o.getHrpCode(), 1D, "");
                            } else {
                                return new HrpOrderKey("", o.getSn(), o.getInvCode(), o.getHrpCode(), -1D, "");
                            }
                        }
                )
        );

        for (HrpOrderKey hrpOrderKey : BillItemHrpMap.keySet()) {
            List<BillItemHrp> billItemHrps = BillItemHrpMap.get(hrpOrderKey);
            List<ThirdParty> thirdParties = ThirdPartyMap.get(hrpOrderKey);
            if (thirdParties == null) continue;

            for (int i = 0; i < billItemHrps.size(); i++) {
                BillItemHrp billItemHrp = billItemHrps.get(i);
                if (thirdParties.size() - 1 >= i) {
                    ThirdParty thirdParty = thirdParties.get(i);
                    this.baseMapper.saveHrpKeyLow(thirdParty.getHrpKey(), thirdParty.getAutoId(), billItemHrp.getSn(), hrpOrderKey.getSkuQty().toString(), hrpOrderKey.getDeptCode());
                }
            }
        }
    }

    private void updateBillItemByHrpLow(List<ThirdParty> thirdPartylist) {
        List<BillItem> itemList = new ArrayList<>();
        List<BillItem> itemListCopy = new ArrayList<>();
        List<BillItemHrp> billItemHrpList = baseMapper.billItemList("0");
        Map<HrpOrderKey, List<BillItemHrp>> BillItemHrpMap = billItemHrpList.stream().collect(
                Collectors.groupingBy(o -> {
                            if (o.getSkuQty() > 0) {
                                return new HrpOrderKey("", o.getSn(), o.getHrpCode(), o.getDeptCode(), 1D * -1, "");
                            } else {
                                return new HrpOrderKey("", o.getSn(), o.getHrpCode(), o.getDeptCode(), 1D, "");
                            }
                        }
                ));

        Map<HrpOrderKey, List<ThirdParty>> ThirdPartyMap = thirdPartylist.stream().collect(
                Collectors.groupingBy(o -> {

                            if (o.getSkuQty() > 0) {
                                return new HrpOrderKey("", o.getSn(), o.getInvCode(), o.getHrpCode(), 1D * -1, "");
                            } else {
                                return new HrpOrderKey("", o.getSn(), o.getInvCode(), o.getHrpCode(), 1D, "");
                            }
                        }
                )
        );

        for (HrpOrderKey hrpOrderKey : BillItemHrpMap.keySet()) {
            List<BillItemHrp> billItemHrps = BillItemHrpMap.get(hrpOrderKey);
            List<ThirdParty> thirdParties = ThirdPartyMap.get(hrpOrderKey);
            if (thirdParties == null) continue;

            for (int i = 0; i < billItemHrps.size(); i++) {
                BillItemHrp billItemHrp = billItemHrps.get(i);
                for (ThirdParty thirdParty : thirdParties) {
                    if (thirdParty.getHrpKey().substring(4, 10).equals(new SimpleDateFormat("yyyyMM").format(billItemHrp.getBusDate()))) {
//                    this.baseMapper.saveHrpKeyLow(thirdParty.getHrpKey(), thirdParty.getAutoId(), billItemHrp.getSn(), hrpOrderKey.getSkuQty().toString(), hrpOrderKey.getDeptCode());
                        //判断是否是本月的HRP入库单据
                        //如果是进行下一步操作,判断记账单中同HRP_ID数量是否小于HRP中同AUTO_ID的数量，如果是再进行拉取
                        float hrpQty = 0;
                        for (BillItem billItem1 : itemListCopy) {
                            if (billItem1.getHrpId().equals(thirdParty.getAutoId())) {
                                hrpQty += billItem1.getSkuQty();
                            }
                        }
                        if (Math.abs(hrpQty) < Math.abs(thirdParty.getSkuQty())) {
                            hrpQty = this.baseMapper.getHrpQty(thirdParty.getAutoId(), DateUtils.format(billItemHrp.getBusDate(), "yyyy-MM"));
                            if (Math.abs(hrpQty) < Math.abs(thirdParty.getSkuQty())) {
                                BillItem billItem = new BillItem();
                                BillItem billItemCopy = new BillItem();
                                billItem.setHrpId(thirdParty.getAutoId());
                                billItem.setHrpKey(thirdParty.getHrpKey());
                                billItem.setId(billItemHrp.getItemId());
                                BeanUtils.copyProperties(billItem, billItemCopy);
                                billItemCopy.setSkuQty(billItemHrp.getSkuQty());
                                itemListCopy.add(billItemCopy);
                                itemList.add(billItem);
                                break;
                            }
                        }
                    }
                }
            }
        }
        if (itemList.size() > 0) {
            this.updateBatchById(itemList);
        }
    }

    private void updateBillItemByHrpHigh() {
        List<BillItemHrp> billItemHrpList = baseMapper.billItemList("1");
        Map<HrpOrderKey, List<BillItemHrp>> BillItemHrpMap = billItemHrpList.stream().collect(
                Collectors.groupingBy(o -> {
                            if (o.getSkuQty() > 0) {
                                return new HrpOrderKey(o.getInpatientNo(), o.getRfid(), o.getHrpCode(), o.getDeptCode(), 1D * -1, DateUtils.format(o.getBusDate(), "yyyy-MM-dd"));
                            } else {
                                return new HrpOrderKey(o.getInpatientNo(), o.getRfid(), o.getHrpCode(), o.getDeptCode(), 1D, DateUtils.format(o.getBusDate(), "yyyy-MM-dd"));
                            }
                        }
                ));
        List<ThirdParty> thirdPartylist = thirdPartyService.list(Wrappers.<ThirdParty>query().ne("IFNULL(patient_no,0)", 0)
                .gt("oprt_date", DateUtils.format(DateUtils.addDays(new Date(), -90), "yyyy-MM-dd")));
        Map<HrpOrderKey, List<ThirdParty>> ThirdPartyMap = thirdPartylist.stream().collect(
                Collectors.groupingBy(o -> {
                            if (o.getSkuQty() > 0) {
                                return new HrpOrderKey(o.getPatientNo(), o.getSn(), o.getInvCode(), o.getHrpCode(), 1D * -1, DateUtils.format(o.getOprtDate(), "yyyy-MM-dd"));
                            } else {
                                return new HrpOrderKey(o.getPatientNo(), o.getSn(), o.getInvCode(), o.getHrpCode(), 1D, DateUtils.format(o.getOprtDate(), "yyyy-MM-dd"));
                            }
                        }
                )
        );

        for (HrpOrderKey hrpOrderKey : BillItemHrpMap.keySet()) {
            List<BillItemHrp> billItemHrps = BillItemHrpMap.get(hrpOrderKey);
            List<ThirdParty> thirdParties = ThirdPartyMap.get(hrpOrderKey);
            if (thirdParties == null) continue;
            for (int i = 0; i < billItemHrps.size(); i++) {
                BillItemHrp billItemHrp = billItemHrps.get(i);
                for (ThirdParty thirdParty : thirdParties) {
                    if (thirdParty.getHrpKey().substring(4, 10).equals(new SimpleDateFormat("yyyyMM").format(billItemHrp.getBusDate()))) {
                        //判断是否是本月的HRP入库单据
                        //如果是进行下一步操作,判断记账单中同HRP_ID数量是否小于HRP中同AUTO_ID的数量，如果是再进行拉取
                        float hrpQty = this.baseMapper.getHrpQty(thirdParty.getAutoId(), DateUtils.format(billItemHrp.getBusDate(), "yyyy-MM"));
                        if (Math.abs(hrpQty) < Math.abs(thirdParty.getSkuQty())) {
                            this.baseMapper.saveHrpKeyHigh(thirdParty.getHrpKey(), thirdParty.getAutoId(), DateUtils.format(billItemHrp.getBusDate(), "yyyy-MM-dd"), billItemHrp.getRfid(),
                                    billItemHrp.getInpatientNo(), hrpOrderKey.getSkuQty(), hrpOrderKey.getDeptCode());
                        }

                    } else {
                        continue;
                    }
                }

            }
        }
    }

    @Override
    public void saveAllSettlement(QueryContext context, BillSettAllDTO billSettAllDTO) {
        this.baseMapper.updateBillItemInvoice(context.getWrapper(),
                billSettAllDTO.getBusType().toString(),
                billSettAllDTO.getSettlementId(),
                BillStatus.SETTLEMENT.getStatus());
        baseMapper.calculateSettlementPrice(billSettAllDTO.getSettlementId());
    }

    @Override
    public void deleteBillAllSettlement(BillSettlementDTO billSettlementDTO) {
        List<BillItem> billItemList = billSettlementDTO.getBillItemIds().stream().map(id -> {
            BillItem billItem = new BillItem();
            billItem.setId(id);
            billItem.setSettlementId("0")
                    .setStatus(BillStatus.DEFAULT.getStatus());
            return billItem;
        }).collect(Collectors.toList());

        if (billItemList.size() > 0) {
            super.updateBatchById(billItemList);
        }
        baseMapper.calculateSettlementPrice(billSettlementDTO.getSettlementId());
    }

    public void updateBillItem(String id, String hrpKey, String hrpId) {
        baseMapper.updateBillItem(id,hrpKey,hrpId);
    }
    @Override
    public Double getSumSkuQty(String startDate, String endDate) {
        return this.baseMapper.getSumSkuQty(startDate, endDate);
    }

    @Override
    public Double getSumAmount(String startDate, String endDate) {
        return this.baseMapper.getSumAmount(startDate, endDate);
    }


    @Override
    public IPage billInPage(QueryContext context) {
        return this.baseMapper.billInPage(context.getPage(), context.getWrapper(), context.getParams());
    }

    @Override
    public List<BillItem> billInList(QueryContext context) {
        return this.baseMapper.billInList( context.getWrapper(), context.getParams());
    }
}
